/*
 * Copyright 2013 Agustina Martinez-Garcia

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
 */
package uk.ljmu.mulgaraifz.httprequests;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

import org.apache.http.client.HttpClient;
import org.apache.log4j.Logger;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.QName;
import org.igfay.jfig.JFig;
import org.igfay.jfig.JFigException;

import uk.ljmu.mulgaraifz.errorhandling.MulgaraException;
import uk.ljmu.mulgaraifz.model.CollectionNode;
import uk.ljmu.mulgaraifz.model.DublinCore;
import uk.ljmu.mulgaraifz.sparql.QueryConstants;
import uk.ljmu.mulgaraifz.utilities.Constants;
import uk.ljmu.mulgaraifz.utilities.XmlTraverse;

public class MulgaraOperationsImpl implements MulgaraOperations {

    private static Logger log = Logger.getLogger(MulgaraOperations.class);

    /**
     * USED INTERNALLY IN THE TREECONSTRUCTION FUNCTION
     */
    private CollectionNode currentNode;

    /**
	 * 
	 */
    private List<CollectionNode> treeList;

    public void setTreeList(List<CollectionNode> treeList) {
	this.treeList = treeList;
    }

    /**
	 * 
	 */
    private HttpManagement httpMan;
    private int numResourcesCollection;

    public void setHttpMan(HttpManagement httpMan) {
	this.httpMan = httpMan;
    }

    public HttpManagement getHttpMan() {
	return httpMan;
    }

    /**
     * @return the treeList
     */
    public List<CollectionNode> getTreeList() {
	return treeList;
    }

    /**
     * Default credentials from config file
     * 
     * @throws MulgaraException
     */
    public MulgaraOperationsImpl() throws MulgaraException {
	String basePath;
	try {
	    basePath = JFig.getInstance().getValue("mulgaraServer", "service");
	    log.debug("Create Mulgara instance, basepath " + basePath);
	    //this.httpMan = new HttpManagement(basePath);
	    this.httpMan = HttpManagement.getInstance();
	} catch (JFigException e) {
	    log.error("Error:", e);
	    throw new MulgaraException(
		    "Unable to initialise parameters from config file, check error log...");
	}
	this.treeList = new ArrayList<CollectionNode>();
    }

    /**
     * 
     * @param user
     *            mulgara user
     * @param password
     *            mulgara passwd
     * @throws MulgaraException
     */
    public MulgaraOperationsImpl(String user, String password)
	    throws MulgaraException {
	/*String basePath;
	try {
	    basePath = JFig.getInstance().getValue("mulgaraServer", "service");
	} catch (JFigException e) {
	    log.error("Error:", e);
	    throw new MulgaraException(
		    "unable to initialise parameters from config file, check error log...");
	}*/
	//this.httpMan = new HttpManagement(basePath);
	this.httpMan = HttpManagement.getInstance();
	this.treeList = new ArrayList<CollectionNode>();
    }

    /**
     * Method that performs an SPARQL query to Mulgara to obtain all the
     * collections defined in the repository instance
     * 
     * @return String array containing the collections identifiers
     */
    public List<String> getRootCollections() throws MulgaraException {
	List<String> mList = new ArrayList<String>();
	String strBody[];
	String constantValue;
	String query = QueryConstants.GET_ROOT_COLS;

	constantValue = JFig.getInstance().getValue("mulgaraServer", "GRAPH",
		HttpManagement.DEFAULT_GRAPH);
	if (!constantValue.startsWith(Constants.ID_SEP_OPEN))
	    constantValue = Constants.ID_SEP_OPEN + constantValue
		    + Constants.ID_SEP_CLOSE;

	query = QueryConstants.parseQuery(query, "GRAPH", constantValue);

	strBody = httpMan.httpSparqlQuery(query, httpMan.get_OutputFormats()
		.get(httpMan.get_OutputFormats().get("xml")));

	// Obtain XML document from results
	Iterator<?> iterator = null;

	iterator = XmlTraverse.createSparqlXMLIterator(strBody[0]);
	if (iterator == null) {
	    log.debug("In getRootCollections, iterator is null");
	    throw new MulgaraException("Empty root collections list...");
	}
	while (iterator.hasNext()) {

	    // Obtain the list of 'binding' elements as a sibling node of
	    // 'result'
	    // For each element 'result' the first binding node is the object
	    // identifier
	    // the second binding element is the data stream name
	    List<?> bindList = ((Element) iterator.next()).elements();
	    Element bind = (Element) bindList.get(0);
	    Element insideBind = (Element) bind.elements().get(0); // Just has
	    // one
	    // element
	    String idData = insideBind.getText();
	    mList.add(idData);
	}
	return mList;
    }

    /**
     * Method that performs an SPARQL query to Mulgara to obtain all the
     * collections defined in the repository instance plus each collection
     * DC:title information.
     * 
     * @return String array containing the collections identifiers
     */
    public List<String> getRootCollectionsTitle() throws MulgaraException {
	List<String> mList = new ArrayList<String>();
	String strBody[];
	String constantValue;
	String query = QueryConstants.GET_ROOT_COLS_TITLE;

	constantValue = JFig.getInstance().getValue("mulgaraServer", "GRAPH",
		HttpManagement.DEFAULT_GRAPH);
	if (!constantValue.startsWith(Constants.ID_SEP_OPEN))
	    constantValue = Constants.ID_SEP_OPEN + constantValue
		    + Constants.ID_SEP_CLOSE;

	query = QueryConstants.parseQuery(query, "GRAPH", constantValue);

	strBody = httpMan.httpSparqlQuery(query, httpMan.get_OutputFormats()
		.get("xml"));

	// Obtain XML document from results
	Iterator<?> iterator = null;

	iterator = XmlTraverse.createSparqlXMLIterator(strBody[0]);

	if (iterator == null) {
	    log
		    .fatal("Iterator null while obtaining Root collections ids and titles...");
	    throw new MulgaraException(
		    "Iterator null while obtaining Root collections ids and titles...");
	}

	while (iterator.hasNext()) {

	    // Obtain the list of 'binding' elements as a sibling node of
	    // 'result'
	    // For each element 'result' the first binding node is the object
	    // identifier
	    // the second binding element is the data stream name
	    List<?> bindList = ((Element) iterator.next()).elements();
	    Element bind = (Element) bindList.get(0);
	    Element insideBind = (Element) bind.elements().get(0); // Fedora
	    // Identifier
	    String idData = insideBind.getText();
	    String title = "";
	    try {
		bind = (Element) bindList.get(1);
		insideBind = (Element) bind.elements().get(0); // DC:title
		title = insideBind.getText();
	    } catch (IndexOutOfBoundsException ex) {
		log.info("Element " + idData
			+ " doesn't present dc:title element.");
	    }

	    mList.add(idData + ";" + title);
	}
	return mList;
    }

    @SuppressWarnings("unused")
    private void getNumberOfChildren(HttpClient instance,
	    String collectionIdentifier) throws MulgaraException {

	String strBody[] = new String[2];
	String constantValue, query = QueryConstants.GET_COLLECTION_CHILDREN;

	constantValue = JFig.getInstance().getValue("mulgaraServer", "GRAPH",
		HttpManagement.DEFAULT_GRAPH);
	if (!constantValue.startsWith(Constants.ID_SEP_OPEN))
	    constantValue = Constants.ID_SEP_OPEN + constantValue
		    + Constants.ID_SEP_CLOSE;

	query = QueryConstants.parseQuery(query, "GRAPH", constantValue);
	query = QueryConstants
		.parseQuery(
			query,
			"COLLECTION_ID",
			(collectionIdentifier
				.contains(Constants.INFO_FEDORA_PREFIX) ? collectionIdentifier
				: Constants.INFO_FEDORA_PREFIX
					+ collectionIdentifier));

	try {
	    strBody = httpMan.httpSparqlQuery(query, httpMan
		    .get_OutputFormats().get("xml"));
	} catch (MulgaraException e) {
	    log.error("Error:", e);
	}

	// Obtain XML document from results
	Iterator<?> iterator = XmlTraverse.createSparqlXMLIterator(strBody[0]);
	if (iterator != null) {
	    while (iterator.hasNext()) {
		numResourcesCollection++;
		List<?> bindList = ((Element) iterator.next()).elements();
		Element bind = (Element) bindList.get(0);
		Element insideBind = (Element) bind.elements().get(0); // Fedora
		// Identifier
		String idData = insideBind.getText();
		if (hasMembers(idData)) {
		    // recursive call
		    getNumberOfChildren(instance, idData);
		}
	    }
	} else {
	    log
		    .fatal("Iterator null while obtaining collections' number of children...");
	    throw new MulgaraException(
		    "Iterator null while obtaining collections' number of children...");
	}
    }

    /**
     * Method that performs an SPARQL query to Mulgara to obtain all the
     * collections information defined in the repository instance
     * 
     * @param identifier
     * @throws MulgaraException
     */
    public DublinCore getCollectionInfo(String identifier)
	    throws MulgaraException {
	String strBody[];
	String constantValue;
	String query = QueryConstants.GET_COL_INFO;

	if (identifier == null || identifier.equals(""))
	    return null;
	constantValue = JFig.getInstance().getValue("mulgaraServer", "GRAPH",
		HttpManagement.DEFAULT_GRAPH);
	if (!constantValue.startsWith(Constants.ID_SEP_OPEN))
	    constantValue = Constants.ID_SEP_OPEN + constantValue
		    + Constants.ID_SEP_CLOSE;

	query = QueryConstants.parseQuery(query, "GRAPH", constantValue);
	query = QueryConstants.parseQuery(query, "IDENTIFIER", identifier);

	strBody = httpMan.httpSparqlQuery(query, httpMan.get_OutputFormats()
		.get("xml"));

	// Obtain XML document from results
	Iterator<?> iterator;

	iterator = XmlTraverse.createRDFIterator(strBody[0]);
	if (iterator == null) {
	    log.fatal("Iterator null while obtaining collections' info...");
	    throw new MulgaraException(
		    "Iterator null while obtaining collections' info...");
	}
	while (iterator.hasNext()) {
	    // Obtain all dc:Elements
	    Element description = (Element) iterator.next();

	    Element title = description.element(new QName("title", description
		    .getNamespaceForPrefix("dc")));
	    Element dcIdentifier = description.element(new QName("identifier",
		    description.getNamespaceForPrefix("dc")));
	    Element source = description.element(new QName("source",
		    description.getNamespaceForPrefix("dc")));
	    Element dcDesc = description.element(new QName("description",
		    description.getNamespaceForPrefix("dc")));
	    Element date = description.element(new QName("date", description
		    .getNamespaceForPrefix("dc")));
	    Element type = description.element(new QName("type", description
		    .getNamespaceForPrefix("rdf")));

	    DublinCore item = new DublinCore();
	    item.setDcDate(date != null ? date.getText() : "");
	    item.setDcDescription(dcDesc != null ? dcDesc.getText() : "");
	    item.setDcIdentifier(identifier != null ? dcIdentifier.getText()
		    : "");
	    item.setDcSource(source != null ? source.getText() : "");
	    item.setDcTitle(title != null ? title.getText() : "");
	    item.setDcType(type != null ? type.attributeValue("resource") : "");

	    boolean getRes = JFig.getInstance().getBooleanValue(
		    "mulgaraServer", "inferenceActive", "false");

	    // Add number of collection's members
	    if (!getRes) {
		// OLD SPARQL SLOW RECURSIVE METHOD
		// getNumberOfChildren(this.getHttpClient(), identifier);
		this.getNumberOfChildrenTQLInstance(identifier);
		item.setNumberOfResources(numResourcesCollection);
		// RESET
		numResourcesCollection = 0;
	    }

	    return item;
	}
	return null;
    }

    /**
     * Method that performs an SPARQL query to Mulgara to obtain all the
     * resources information associated with one collection
     * 
     * @param colIdentifier
     * @throws MulgaraException
     */
    public void getResourcesInfo(String colIdentifier) throws MulgaraException {
	String strBody[];
	String query = QueryConstants.GET_RESOURCES_INFO;
	String constantValue;

	constantValue = JFig.getInstance().getValue("mulgaraServer", "GRAPH",
		HttpManagement.DEFAULT_GRAPH);
	if (!constantValue.startsWith(Constants.ID_SEP_OPEN))
	    constantValue = Constants.ID_SEP_OPEN + constantValue
		    + Constants.ID_SEP_CLOSE;

	query = QueryConstants.parseQuery(query, "GRAPH", constantValue);
	query = QueryConstants.parseQuery(query, "IDENTIFIER", colIdentifier);
	strBody = httpMan.httpSparqlQuery(query, httpMan.get_OutputFormats()
		.get("xml"));

	// Obtain XML document from results
	Iterator<?> iterator = XmlTraverse.createRDFIterator(strBody[0]);
	if (iterator == null) {
	    log
		    .fatal("Iterator null or empty results while obtaining resources' information...");
	    throw new MulgaraException(
		    "Iterator null or empty results while obtaining resources' information...");
	}

	while (iterator.hasNext()) {
	    // Obtain all dc:Elements
	    Element description = (Element) iterator.next();
	    Element title = description.element("title");
	    Element identifier = description.element("identifier");
	    Element creator = description.element("creator");
	    Element dcDesc = description.element("description");
	    Element date = description.element("date");
	    Element type = description.element("type");
	    Element source = description.element("source");

	    DublinCore item = new DublinCore();
	    item.setDcDate(date != null ? date.getText() : "");
	    item.setDcDescription(dcDesc != null ? dcDesc.getText() : "");
	    item
		    .setDcIdentifier(identifier != null ? identifier.getText()
			    : "");
	    item.setDcCreator(creator != null ? creator.getText() : "");
	    item.setDcTitle(title != null ? title.getText() : "");
	    item.setDcType(type != null ? type.getText() : "");
	    item.setDcSource(source != null ? source.getText() : "");

	    httpMan.getResourceInfo().put(description.attributeValue("about"),
		    item);
	}
    }

    /**
     * Method that performs an SPARQL query to Mulgara to obtain all the
     * resources information associated with one collection
     * 
     * @param colIdentifier
     * @throws MulgaraException
     */
    public List<String> getCollectionChildren(String colIdentifier) throws MulgaraException {
	String strBody[];
	List<String> mList = new ArrayList<String>();

	String query = QueryConstants.GET_COLLECTION_CHILDREN;
	String constantValue;

	constantValue = JFig.getInstance().getValue("mulgaraServer", "GRAPH",
		HttpManagement.DEFAULT_GRAPH);
	if (!constantValue.startsWith(Constants.ID_SEP_OPEN))
	    constantValue = Constants.ID_SEP_OPEN + constantValue
		    + Constants.ID_SEP_CLOSE;

	query = QueryConstants.parseQuery(query, "GRAPH", constantValue);
	// This query needs a fullId so check that the collection identifier
	// presents the prefix 'info:fedora'
	if (!colIdentifier.contains(Constants.INFO_FEDORA_PREFIX))
	    colIdentifier = Constants.INFO_FEDORA_PREFIX + colIdentifier;

	query = QueryConstants
		.parseQuery(query, "COLLECTION_ID", colIdentifier);

	strBody = httpMan.httpSparqlQuery(query, httpMan
		.get_OutputFormats().get("xml"));

	// Obtain XML document from results
	Iterator<?> iterator = null;
	iterator = XmlTraverse.createSparqlXMLIterator(strBody[0]);
	if (iterator == null) {
	    log
		    .fatal("Iterator null in getCollectionChildren, empty results...");
	    throw new MulgaraException(
		    "Iterator null in getCollectionChildren, empty results...s");
	}
	while (iterator.hasNext()) {

	    // Obtain the list of 'binding' elements as a sibling node of
	    // 'result'
	    // For each element 'result' the first binding node is the object
	    // identifier
	    // the second binding element is the data stream name
	    List<?> bindList = ((Element) iterator.next()).elements();
	    Element bind = (Element) bindList.get(0);
	    // Just has one nested element
	    Element insideBind = (Element) bind.elements().get(0);
	    String idData = insideBind.getText();
	    mList.add(idData);
	}

	return mList;
    }

    /**
     * Method that performs an SPARQL query to Mulgara to obtain all the
     * resources information associated with one collection
     * 
     * @param colIdentifier
     * @throws MulgaraException
     */
    public List<String> getCollectionChildrenTitle(String colIdentifier) throws MulgaraException {
	String strBody[];
	List<String> mList = new ArrayList<String>();

	String query = QueryConstants.GET_COLLECTION_CHILDREN_TITLE;
	String constantValue;

	constantValue = JFig.getInstance().getValue("mulgaraServer", "GRAPH",
		HttpManagement.DEFAULT_GRAPH);
	if (!constantValue.startsWith(Constants.ID_SEP_OPEN))
	    constantValue = Constants.ID_SEP_OPEN + constantValue
		    + Constants.ID_SEP_CLOSE;

	query = QueryConstants.parseQuery(query, "GRAPH", constantValue);
	// This query needs a fullId so check that the collection identifier
	// presents the prefix 'info:fedora'
	if (!colIdentifier.contains(Constants.INFO_FEDORA_PREFIX))
	    colIdentifier = Constants.INFO_FEDORA_PREFIX + colIdentifier;
	query = QueryConstants
		.parseQuery(query, "COLLECTION_ID", colIdentifier);

	strBody = httpMan.httpSparqlQuery(query, httpMan
		.get_OutputFormats().get("xml"));

	// Obtain XML document from results
	Iterator<?> iterator = null;
	iterator = XmlTraverse.createSparqlXMLIterator(strBody[0]);
	if (iterator == null) {
	    log
		    .info("Iterator null in getCollectionChildrenTitle, empty results, collection does not have children...");
	    // throw new
	    // MulgaraException("Empty results, getCollectionChildrenTitle");
	    return mList;
	}

	while (iterator.hasNext()) {

	    // Obtain the list of 'binding' elements as a sibling node of
	    // 'result'
	    // For each element 'result' the first binding node is the object
	    // identifier
	    // the second binding element is the data stream name
	    List<?> bindList = ((Element) iterator.next()).elements();
	    Element bind = (Element) bindList.get(0);
	    Element insideBind = (Element) bind.elements().get(0); // FEDORA
	    // identifier
	    String idData = insideBind.getText();
	    String title = "";
	    try {
		bind = (Element) bindList.get(1);
		insideBind = (Element) bind.elements().get(0); // DC:title
		title = insideBind.getText();
	    } catch (IndexOutOfBoundsException ex) {
		log.info("Element " + idData
			+ " doesn't present dc:title element.");
	    }
	    mList.add(idData + ";" + title);
	}

	return mList;
    }

    private List<String> getCollectionChildrenTitleQudex(String colIdentifier) throws MulgaraException {
	String strBody[];
	List<String> mList = new ArrayList<String>();

	String query = QueryConstants.QUDEX_GET_COLLECTION_CHILDREN_TITLE;
	String constantValue;

	constantValue = JFig.getInstance().getValue("mulgaraServer", "GRAPH",
		HttpManagement.DEFAULT_GRAPH);
	if (!constantValue.startsWith(Constants.ID_SEP_OPEN))
	    constantValue = Constants.ID_SEP_OPEN + constantValue
		    + Constants.ID_SEP_CLOSE;

	query = QueryConstants.parseQuery(query, "GRAPH", constantValue);
	// This query needs a fullId so check that the collection identifier
	// presents the prefix 'info:fedora'
	if (!colIdentifier.contains(Constants.INFO_FEDORA_PREFIX))
	    colIdentifier = Constants.INFO_FEDORA_PREFIX + colIdentifier;
	query = QueryConstants
		.parseQuery(query, "COLLECTION_ID", colIdentifier);

	strBody = httpMan.httpSparqlQuery(query, httpMan
		.get_OutputFormats().get("xml"));

	// Obtain XML document from results
	Iterator<?> iterator = null;
	iterator = XmlTraverse.createSparqlXMLIterator(strBody[0]);
	if (iterator == null) {
	    log
		    .info("Iterator null in getCollectionChildrenTitle, empty results, collection does not have children...");
	    // throw new
	    // MulgaraException("Empty results, getCollectionChildrenTitle");
	    return mList;
	}

	while (iterator.hasNext()) {

	    // Obtain the list of 'binding' elements as a sibling node of
	    // 'result'
	    // For each element 'result' the first binding node is the object
	    // identifier
	    // the second binding element is the data stream name
	    List<?> bindList = ((Element) iterator.next()).elements();
	    Element bind = (Element) bindList.get(0);
	    Element insideBind = (Element) bind.elements().get(0); // FEDORA
	    // identifier
	    String idData = insideBind.getText();
	    String title = "";
	    try {
		bind = (Element) bindList.get(1);
		insideBind = (Element) bind.elements().get(0); // DC:title
		title = insideBind.getText();
	    } catch (IndexOutOfBoundsException ex) {
		log.info("Element " + idData
			+ " doesn't present dc:title element.");
	    }
	    mList.add(idData + ";" + title);
	}

	return mList;
    }

    private boolean hasMembers(String identifier)
	    throws MulgaraException {
	String strBody[] = new String[2];

	String query = QueryConstants.GET_COLLECTION_CHILDREN;
	String constantValue;

	constantValue = JFig.getInstance().getValue("mulgaraServer", "GRAPH",
		HttpManagement.DEFAULT_GRAPH);
	if (!constantValue.startsWith(Constants.ID_SEP_OPEN))
	    constantValue = Constants.ID_SEP_OPEN + constantValue
		    + Constants.ID_SEP_CLOSE;

	query = QueryConstants.parseQuery(query, "GRAPH", constantValue);
	query = QueryConstants.parseQuery(query, "COLLECTION_ID", identifier);

	try {
	    strBody = httpMan.httpSparqlQuery(query, httpMan
		    .get_OutputFormats().get("xml"));
	} catch (MulgaraException e) {
	    log.error("Error:", e);
	}

	// Obtain XML document from results
	Iterator<?> iterator = XmlTraverse.createSparqlXMLIterator(strBody[0]);
	if (iterator == null) {
	    log.fatal("Empty results in method hasMembers...");
	    throw new MulgaraException("Empty results in method hasMembers");
	}
	if (iterator.hasNext())
	    return true;
	else
	    return false;
    }

    private boolean hasMembersQudex(HttpClient instance, String identifier)
	    throws MulgaraException {
	String strBody[] = new String[2];

	String query = QueryConstants.QUDEX_GET_COLLECTION_CHILDREN;
	String constantValue;

	constantValue = JFig.getInstance().getValue("mulgaraServer", "GRAPH",
		HttpManagement.DEFAULT_GRAPH);
	if (!constantValue.startsWith(Constants.ID_SEP_OPEN))
	    constantValue = Constants.ID_SEP_OPEN + constantValue
		    + Constants.ID_SEP_CLOSE;

	query = QueryConstants.parseQuery(query, "GRAPH", constantValue);
	query = QueryConstants.parseQuery(query, "COLLECTION_ID", identifier);

	try {
	    strBody = httpMan.httpSparqlQuery(query, httpMan
		    .get_OutputFormats().get("xml"));
	} catch (MulgaraException e) {
	    log.error("Error:", e);
	}

	// Obtain XML document from results
	Iterator<?> iterator = XmlTraverse.createSparqlXMLIterator(strBody[0]);
	if (iterator == null) {
	    log.fatal("Empty results in method hasMembers...");
	    throw new MulgaraException("Empty results in method hasMembers");
	}
	if (iterator.hasNext())
	    return true;
	else
	    return false;
    }

    /**
     * @param currentDate
     * @throws MulgaraException
     */
    public List<String> getRecentCollections(String currentDate)
	    throws MulgaraException {
	List<String> mList = new ArrayList<String>();
	String strBody[] = new String[2];

	String query = QueryConstants.GET_RECENT_COLLECTIONS;
	String constantValue;

	constantValue = JFig.getInstance().getValue("mulgaraServer", "GRAPH",
		HttpManagement.DEFAULT_GRAPH);
	if (!constantValue.startsWith(Constants.ID_SEP_OPEN))
	    constantValue = Constants.ID_SEP_OPEN + constantValue
		    + Constants.ID_SEP_CLOSE;

	query = QueryConstants.parseQuery(query, "GRAPH", constantValue);
	query = QueryConstants.parseQuery(query, "DATE", currentDate);

	strBody = httpMan.httpSparqlQuery(query, httpMan.get_OutputFormats()
		.get("xml"));

	// Obtain XML document from results
	Iterator<?> iterator = XmlTraverse.createSparqlXMLIterator(strBody[0]);

	if (iterator != null) {
	    while (iterator.hasNext()) {
		// Obtain the list of 'binding' elements as a sibling node of
		// 'result'
		// For each element 'result' the first binding node is the
		// object identifier
		// the second binding element is the data stream name
		/**
		 * <result> <binding name="s"> <uri>info:fedora/demo:224</uri>
		 * </binding> <binding name="o"> <literal
		 * datatype="http://www.w3.org/2001/XMLSchema#dateTime"
		 * >2010-01-18T10:15:36.601Z</literal> </binding> </result>
		 */
		List<?> bindList = ((Element) iterator.next()).elements();
		Element bind = (Element) bindList.get(0);
		Element insideBind = (Element) bind.elements().get(0); // FEDORA
		// ID
		String idData = insideBind.getText();
		bind = (Element) bindList.get(1);
		insideBind = (Element) bind.elements().get(0); // CREATION DATE
		String dateData = insideBind.getText();
		mList.add(idData + ";" + dateData);
	    }
	} else {
	    log.fatal("In getRecentCollections, iterator null, empty results");
	    throw new MulgaraException(
		    "In getRecentCollections, iterator null, empty results");
	}
	return mList;
    }

    /**
     * @param currentDate
     * @throws MulgaraException
     */
    public List<String> getRecentCollectionsTitle(String currentDate)
	    throws MulgaraException {
	List<String> mList = new ArrayList<String>();
	String strBody[] = new String[2];

	String query = QueryConstants.GET_RECENT_COLLECTIONS_TITLE;
	String constantValue;

	constantValue = JFig.getInstance().getValue("mulgaraServer", "GRAPH",
		HttpManagement.DEFAULT_GRAPH);
	if (!constantValue.startsWith(Constants.ID_SEP_OPEN))
	    constantValue = Constants.ID_SEP_OPEN + constantValue
		    + Constants.ID_SEP_CLOSE;

	query = QueryConstants.parseQuery(query, "GRAPH", constantValue);
	query = QueryConstants.parseQuery(query, "DATE", currentDate);

	try {
	    strBody = httpMan.httpSparqlQuery(query, httpMan
		    .get_OutputFormats().get("xml"));
	} catch (MulgaraException e) {
	    log.error("Error:", e);
	}

	// Obtain XML document from results
	Iterator<?> iterator = XmlTraverse.createSparqlXMLIterator(strBody[0]);
	if (iterator == null) {
	    log
		    .fatal("In getRecentCollectionsTitle method, empty results, iterator null...");
	    throw new MulgaraException(
		    "In getRecentCollectionsTitle method, empty results, iterator null...");
	}
	if (iterator != null) {
	    while (iterator.hasNext()) {
		// Obtain the list of 'binding' elements as a sibling node of
		// 'result'
		// For each element 'result' the first binding node is the
		// object identifier
		// the second binding element is the data stream name
		/**
		 * <result> <binding name="s"> <uri>info:fedora/demo:224</uri>
		 * </binding> <binding name="o"> <literal
		 * datatype="http://www.w3.org/2001/XMLSchema#dateTime"
		 * >2010-01-18T10:15:36.601Z</literal> </binding> <binding
		 * name="title"> <literal>Title whatever it is</literal>
		 * </binding> </result>
		 */
		List<?> bindList = ((Element) iterator.next()).elements();
		Element bind = (Element) bindList.get(0);
		Element insideBind = (Element) bind.elements().get(0); // FEDORA
		// ID
		String idData = insideBind.getText();
		bind = (Element) bindList.get(1);
		insideBind = (Element) bind.elements().get(0); // CREATION DATE
		String dateData = insideBind.getText();
		// mList.add(idData + ";" + dateData);
		String title = "";
		try {
		    bind = (Element) bindList.get(2);
		    insideBind = (Element) bind.elements().get(0); // DC TITLE
		    title = insideBind.getText();
		} catch (Exception ex) {
		    log.info("Element: " + idData
			    + " doesn't have title element.");
		}
		mList.add(idData + ";" + dateData + ";" + title);
	    }
	}

	return mList;
    }

    /**
     * @param identifier
     * @throws MulgaraException
     */
    public List<String> getRecentResources(String identifier)
	    throws MulgaraException {
	List<String> mList = new ArrayList<String>();
	String strBody[] = new String[2];

	String query = QueryConstants.GET_RECENT_RESOURCES_BY_COLLECTION;
	String constantValue;

	constantValue = JFig.getInstance().getValue("mulgaraServer", "GRAPH",
		HttpManagement.DEFAULT_GRAPH);
	if (!constantValue.startsWith(Constants.ID_SEP_OPEN))
	    constantValue = Constants.ID_SEP_OPEN + constantValue
		    + Constants.ID_SEP_CLOSE;

	query = QueryConstants.parseQuery(query, "GRAPH", constantValue);
	query = QueryConstants.parseQuery(query, "COL_ID", !identifier
		.contains("info:fedora") ? Constants.INFO_FEDORA_PREFIX
		+ identifier : identifier);

	strBody = httpMan.httpSparqlQuery(query, httpMan.get_OutputFormats()
		.get("xml"));

	// Obtain XML document from results
	Iterator<?> iterator = XmlTraverse.createSparqlXMLIterator(strBody[0]);

	if (iterator != null) {
	    while (iterator.hasNext()) {
		// Obtain the list of 'binding' elements as a sibling node of
		// 'result'
		// For each element 'result' the first binding node is the
		// object identifier
		// the second binding element is the data stream name
		/**
		 * <result> <binding name="id">
		 * <literal>info:fedora/whatever-id</literal> </binding>
		 * <binding name="date"> <literal
		 * datatype="http://www.w3.org/2001/XMLSchema#dateTime"
		 * >2010-01-18T10:15:36.601Z</literal> </binding> <binding
		 * name="title"> <literal>Title whatever it is</literal>
		 * </binding> </result>
		 */
		List<?> bindList = ((Element) iterator.next()).elements();
		Element bind = (Element) bindList.get(0);
		Element insideBind = (Element) bind.elements().get(0); // ID
		String id = insideBind.getText();

		bind = (Element) bindList.get(1);
		insideBind = (Element) bind.elements().get(0); // CREATION DATE
		String dateData = insideBind.getText();
		String titleData = "";
		try {
		    bind = (Element) bindList.get(2);
		    insideBind = (Element) bind.elements().get(0); // Title if
		    // present
		    titleData = insideBind.getText();
		} catch (Exception ex) {
		    log.info("Title not present: " + ex.getMessage());
		}

		StringBuilder sb = new StringBuilder();
		sb.append(id);
		sb.append(";");
		sb.append(dateData);
		sb.append(";");
		sb.append(titleData);

		mList.add(sb.toString());
	    }
	} else {
	    log
		    .fatal("In method getRecentResources, empty results, iterator null...");
	    throw new MulgaraException(
		    "In method getRecentResources, empty results, iterator null...");
	}

	return mList;
    }

    /**
     * @param namespace
     * @throws MulgaraException
     * 
     */
    public List<String> getObjectsTitles(String namespace)
	    throws MulgaraException {
	List<String> mList = new ArrayList<String>();
	String strBody[] = new String[2];

	String query = QueryConstants.GET_OBJECTS_BY_NS;
	String constantValue;

	constantValue = JFig.getInstance().getValue("mulgaraServer", "GRAPH",
		HttpManagement.DEFAULT_GRAPH);
	if (!constantValue.startsWith(Constants.ID_SEP_OPEN))
	    constantValue = Constants.ID_SEP_OPEN + constantValue
		    + Constants.ID_SEP_CLOSE;

	query = QueryConstants.parseQuery(query, "GRAPH", constantValue);
	query = QueryConstants.parseQuery(query, "NS", namespace);

	strBody = httpMan.httpSparqlQuery(query, httpMan.get_OutputFormats()
		.get("xml"));

	// Obtain XML document from results
	Iterator<?> iterator = XmlTraverse.createSparqlXMLIterator(strBody[0]);

	if (iterator != null) {
	    while (iterator.hasNext()) {
		// Obtain the list of 'binding' elements as a sibling node of
		// 'result'
		// For each element 'result' the first binding node is the
		// object identifier
		// the second binding element is the data stream name
		/**
		 * <result> <binding name="identifier">
		 * <literal>ns:something</literal> </binding> <binding
		 * name="title"> <literal>Title whatever it is</literal>
		 * </binding> </result>
		 */
		List<?> bindList = ((Element) iterator.next()).elements();
		Element bind = (Element) bindList.get(0);
		Element insideBind = (Element) bind.elements().get(0); // identifier
		String dateData = insideBind.getText();
		String titleData = "";
		try {
		    bind = (Element) bindList.get(1);
		    insideBind = (Element) bind.elements().get(0); // Title if
		    // present
		    titleData = insideBind.getText();
		} catch (Exception ex) {
		    log.info("Title not present: " + ex.getMessage());
		}
		mList.add(dateData + ";" + titleData);
	    }
	} else {
	    log
		    .fatal("In method getObjectsTitles, empty results, iterator null...");
	    throw new MulgaraException(
		    "In method getObjectsTitles, empty results, iterator null...");
	}

	return mList;
    }

    /**
     * @param collectionsIDs
     * @throws MulgaraException
     */
    public void callRecursiveCollectionsTree(List<String> collectionsIDs)
	    throws MulgaraException {
	for (String identifier : collectionsIDs) {
	    recursiveCollectionsTree(identifier);
	}
    }

    /**
     * 
     * @param collectionsIDs
     * @throws MulgaraException
     */
    public void callRecursiveCollectionsTreeNoChildren(
	    List<String> collectionsIDs) throws MulgaraException {
	HttpClient client = HttpManagement.getHttpClient();
	for (String identifier : collectionsIDs) {
	    recursiveCollectionsTreeNoChildren(client, identifier);
	}
    }

    /**
     * 
     * @param collectionsIDs
     * @throws MulgaraException
     */
    public void callRecursiveCollectionsTreeNoChildrenQudex(
	    List<String> collectionsIDs) throws MulgaraException {
	HttpClient client = HttpManagement.getHttpClient();
	for (String identifier : collectionsIDs) {
	    recursiveCollectionsTreeNoChildrenQudex(client, identifier);
	}
    }

    /**
     * 
     * @param collectionID
     *            collection identifier
     * @throws MulgaraException
     */
    private void recursiveCollectionsTree(String collectionID) throws MulgaraException {
	// GET IDENTIFIERS OF THE CHILDREN FOR THE GIVEN COLLECTION
	List<String> mList = new ArrayList<String>();
	String[] splitList = collectionID.split(";");
	String title = "";
	if (splitList != null) {
	    collectionID = splitList[0];
	    if (splitList.length > 1)
		title = splitList[1];
	}
	try {
	    mList = getCollectionChildrenTitle(collectionID);
	} catch (MulgaraException e) {
	    log.error("Error:", e);
	}
	if (mList == null)
	    return;
	CollectionNode node = null;
	nodeExists(collectionID, treeList);

	if (currentNode == null) {
	    node = new CollectionNode(collectionID.replace(
		    Constants.INFO_FEDORA_PREFIX, ""), true);
	    node.setWildcardID(collectionID);
	    if (mList.size() > 0)
		node.setChild(true);
	    else
		node.setChild(false);
	    node.setTitle(title);
	    node.setIsCollection(true);
	    treeList.add(node);
	} else {
	    node = currentNode;
	    currentNode = null;
	}

	for (String item : mList) {
	    String title2 = "";
	    String[] splitListChildren = item.split(";");

	    if (splitListChildren != null) {
		item = splitListChildren[0];
		if (splitListChildren.length > 1)
		    title2 = splitListChildren[1];
	    }
	    CollectionNode child = new CollectionNode(item.replace(
		    Constants.INFO_FEDORA_PREFIX, ""), true);
	    // ADD here collection checking: is the item a collection?
	    try {
		if (isCollection(item))
		    child.setIsCollection(true);
		else
		    child.setIsCollection(false);
	    } catch (MulgaraException e) {
		log.error("Error:", e);
	    }
	    child.setTitle(title2);
	    node.getChildren().add(child);
	    // Check if they have more children or not
	    if (hasMembers(item)) {
		// RECURSIVE CALL
		child.setChild(true);
		child.setWildcardID(item);
		recursiveCollectionsTree(item);
	    } else {
		// FILL IN CUSTOM NODE
		child.setChild(false);
		child.setWildcardID(item);
	    }
	}
    }

    /**
     * 
     * @param collectionID
     *            collection identifier
     * @throws MulgaraException
     */
    private void recursiveCollectionsTreeNoChildren(HttpClient instance,
	    String collectionID) throws MulgaraException {
	// GET IDENTIFIERS OF THE CHILDREN FOR THE GIVEN COLLECTION
	List<String> mList = new ArrayList<String>();
	String[] splitList = collectionID.split(";");
	String title = "";
	if (splitList != null) {
	    collectionID = splitList[0];
	    if (splitList.length > 1)
		title = splitList[1];
	}
	CollectionNode node = null;

	// Check doesn't appear repeated, the node
	nodeExists(collectionID, treeList);

	if (currentNode == null) {
	    node = new CollectionNode(collectionID.replace(
		    Constants.INFO_FEDORA_PREFIX, ""), false);
	    node.setWildcardID(collectionID);

	    if (mList.size() == 0)
		node.setChild(false);
	    node.setTitle(title);
	    node.setIsCollection(true);
	    treeList.add(node);
	} else {
	    node = currentNode;
	    currentNode = null;
	}
	mList = getCollectionChildrenTitle(collectionID);
	// log.info(mList != null ? mList.size() : 0);
	if (mList.size() == 0)
	    return;

	for (String item : mList) {
	    String title2 = "";
	    String[] splitListChildren = item.split(";");

	    if (splitListChildren != null) {
		item = splitListChildren[0];
		if (splitListChildren.length > 1)
		    title2 = splitListChildren[1];
	    }
	    // ADD here collection checking: is the item a collection?
	    if (isCollection(item)) {
		CollectionNode child = new CollectionNode(item.replace(
			Constants.INFO_FEDORA_PREFIX, ""), false);
		child.setIsCollection(true);
		child.setTitle(title2);
		// We set parent hasChildren here once we found it presents a
		// subcollection
		node.setChild(true);
		node.getChildren().add(child);
		// Check if they have more children or not
		if (hasMembers(item)) {
		    // RECURSIVE CALL
		    // child.setChild(true);
		    child.setWildcardID(item);
		    recursiveCollectionsTreeNoChildren(instance, item);
		} else {
		    // FILL IN CUSTOM NODE
		    child.setChild(false);
		    child.setWildcardID(item);
		}
	    } else {
		continue;
	    }
	}
    }

    /**
     * 
     * @param collectionID
     *            collection identifier
     * @throws MulgaraException
     */
    private void recursiveCollectionsTreeNoChildrenQudex(HttpClient instance,
	    String collectionID) throws MulgaraException {
	// GET IDENTIFIERS OF THE CHILDREN FOR THE GIVEN COLLECTION
	List<String> mList = new ArrayList<String>();
	String[] splitList = collectionID.split(";");
	String title = "";
	if (splitList != null) {
	    collectionID = splitList[0];
	    if (splitList.length > 1)
		title = splitList[1];
	}
	CollectionNode node = null;

	// Check doesn't appear repeated, the node
	nodeExists(collectionID, treeList);

	if (currentNode == null) {
	    node = new CollectionNode(collectionID.replace(
		    Constants.INFO_FEDORA_PREFIX, ""), false);
	    node.setWildcardID(collectionID);

	    if (mList.size() == 0)
		node.setChild(false);
	    node.setTitle(title);
	    node.setIsCollection(true);
	    treeList.add(node);
	} else {
	    node = currentNode;
	    currentNode = null;
	}
	mList = getCollectionChildrenTitleQudex(collectionID);

	if (mList.size() == 0)
	    return;

	for (String item : mList) {
	    String title2 = "";
	    String[] splitListChildren = item.split(";");

	    if (splitListChildren != null) {
		item = splitListChildren[0];
		if (splitListChildren.length > 1)
		    title2 = splitListChildren[1];
	    }
	    // ADD here collection checking: is the item a collection?
	    if (isCollection(item)) {
		CollectionNode child = new CollectionNode(item.replace(
			Constants.INFO_FEDORA_PREFIX, ""), false);
		child.setIsCollection(true);
		child.setTitle(title2);
		// We set parent hasChildren here once we found it presents a
		// subcollection
		node.setChild(true);
		node.getChildren().add(child);
		// Check if they have more children or not
		if (hasMembersQudex(instance, item)) {
		    // RECURSIVE CALL
		    // child.setChild(true);
		    child.setWildcardID(item);
		    recursiveCollectionsTreeNoChildrenQudex(instance, item);
		} else {
		    // FILL IN CUSTOM NODE
		    child.setChild(false);
		    child.setWildcardID(item);
		}
	    } else {
		continue;
	    }
	}
    }

    /**
     * 
     * @param item
     * @return
     * @throws MulgaraException
     */
    private boolean isCollection(String item)
	    throws MulgaraException {
	boolean collection = false;
	String strBody[];

	String query = QueryConstants.IS_COLLECTION;
	String constantValue;

	constantValue = JFig.getInstance().getValue("mulgaraServer", "GRAPH",
		HttpManagement.DEFAULT_GRAPH);
	if (!constantValue.startsWith(Constants.ID_SEP_OPEN))
	    constantValue = Constants.ID_SEP_OPEN + constantValue
		    + Constants.ID_SEP_CLOSE;

	query = QueryConstants.parseQuery(query, "GRAPH", constantValue);
	query = QueryConstants.parseQuery(query, "ID", item);

	strBody = httpMan.httpSparqlQuery(query, httpMan
		.get_OutputFormats().get("xml"));

	// Obtain XML document from results
	Iterator<?> iterator = null;
	iterator = XmlTraverse.createSparqlXMLIterator(strBody[0]);
	if (iterator == null) {
	    collection = false;
	    return collection;
	}
	if (iterator != null && iterator.hasNext())
	    collection = true;
	return collection;
    }

    /**
     * 
     * @param id
     * @param mList
     */
    private void nodeExists(String id, List<CollectionNode> mList) {
	for (CollectionNode node : mList) {
	    if (node.getWildcardID().equalsIgnoreCase(id))
		currentNode = node;
	    else {
		// Check Children
		if (node.hasChild()) {
		    nodeExists(id, node.getChildren());
		}
	    }
	}
    }

    /**
     * Clean the Mulgara collections tree
     */
    public void resetTree() {
	treeList = new ArrayList<CollectionNode>();
	currentNode = null;
    }

    // TQL FUNCTIONS
    /**
     * @param collectionIdentifier
     * @throws JFigException
     */
    public String getNumberOfChildrenTQL(String collectionIdentifier)
	    throws MulgaraException {

	String strBody[] = new String[2];
	String constantValue, query = QueryConstants.GET_COLLECTION_CHILDREN_ITQL;

	constantValue = JFig.getInstance().getValue("mulgaraServer", "GRAPH",
		HttpManagement.DEFAULT_GRAPH);
	if (!constantValue.startsWith(Constants.ID_SEP_OPEN))
	    constantValue = Constants.ID_SEP_OPEN + constantValue
		    + Constants.ID_SEP_CLOSE;

	query = QueryConstants.parseQuery(query, "GRAPH", constantValue);
	query = QueryConstants
		.parseQuery(
			query,
			"COL_ID",
			(collectionIdentifier
				.contains(Constants.INFO_FEDORA_PREFIX) ? collectionIdentifier
				: Constants.INFO_FEDORA_PREFIX
					+ collectionIdentifier));

	strBody = httpMan.httpItqlQuery(query, httpMan.get_OutputFormats()
		.get("xml"));

	// Obtain XML document from results
	// Parse results
	/*
	 * <?xml version="1.0" encoding="UTF-8"?> <answer
	 * xmlns="http://mulgara.org/tql#"> <query> <variables><k0/></variables>
	 * <solution><k0
	 * datatype="http://www.w3.org/2001/XMLSchema#integer">162<
	 * /k0></solution> </query> </answer>
	 */
	Document doc = XmlTraverse.getDocument(strBody[0]);
	if (doc == null) {
	    throw new MulgaraException(
		    "Error obtaining number of resources for collection: "
			    + collectionIdentifier);
	}

	try {
	    Element root = doc.getRootElement(); // Element 'answer'
	    Element queryElement = root.element("query");
	    Element solutionElement = (Element) queryElement
		    .element("solution").elements().get(0);
	    numResourcesCollection = Integer
		    .parseInt(solutionElement.getText());
	} catch (Exception ex) {
	    log.fatal(ex.getMessage());
	    numResourcesCollection = 0;
	}

	return String.valueOf(numResourcesCollection);
    }
    
    // TQL FUNCTIONS    
    private void getNumberOfChildrenTQLInstance(String collectionIdentifier) {
	try {
	    int numR = getNumberOfChildrenTQLInstance(collectionIdentifier, QueryConstants.GET_COLLECTION_CHILDREN_ITQL);
	    if (numR == 0) {
		numR = getNumberOfChildrenTQLInstance(collectionIdentifier, QueryConstants.GET_COLLECTION_CHILDREN_ITQL_QUDEX);
	    }
	    
	    this.numResourcesCollection = numR;
	} catch (MulgaraException e) {
	    log.error("Error:", e);
	    this.numResourcesCollection = 0;
	}
    }
    /**
     * @param instance
     * @param collectionIdentifier
     */
    private int getNumberOfChildrenTQLInstance(String collectionIdentifier, String queryP) throws MulgaraException {

	String strBody[] = new String[2];
	String constantValue, query = queryP;

	constantValue = JFig.getInstance().getValue("mulgaraServer", "GRAPH",
		HttpManagement.DEFAULT_GRAPH);
	if (!constantValue.startsWith("<"))
	    constantValue = "<" + constantValue + ">";

	query = QueryConstants.parseQuery(query, "GRAPH", constantValue);
	query = QueryConstants
		.parseQuery(
			query,
			"COL_ID",
			(collectionIdentifier
				.contains(Constants.INFO_FEDORA_PREFIX) ? collectionIdentifier
				: Constants.INFO_FEDORA_PREFIX
					+ collectionIdentifier));

	strBody = httpMan.httpItqlQuery(query, httpMan
		.get_OutputFormats().get("xml"));

	// Obtain XML document from results
	// Parse results
	/*
	 * <?xml version="1.0" encoding="UTF-8"?> <answer
	 * xmlns="http://mulgara.org/tql#"> <query> <variables><k0/></variables>
	 * <solution><k0
	 * datatype="http://www.w3.org/2001/XMLSchema#integer">162<
	 * /k0></solution> </query> </answer>
	 */
	Document doc = XmlTraverse.getDocument(strBody[0]);
	if (doc == null) {
	    throw new MulgaraException(
		    "Error obtaining number of resources for collection: "
			    + collectionIdentifier);
	}

	try {
	    Element root = doc.getRootElement(); // Element 'answer'
	    Element queryElement = root.element("query");
	    Element solutionElement = (Element) queryElement
		    .element("solution").elements().get(0);
	    return Integer
		    .parseInt(solutionElement.getText());
	} catch (Exception ex) {
	    numResourcesCollection = 0;
	    throw new MulgaraException(ex.getMessage());
	}
    }

    public HashMap<String, DublinCore> getResourceInfo() {
	return httpMan.getResourceInfo();
    }

    public List<String> getCollections(String query) throws MulgaraException {
	List<String> mList = new ArrayList<String>();
	String strBody[];
	String constantValue;

	constantValue = JFig.getInstance().getValue("mulgaraServer", "GRAPH",
		HttpManagement.DEFAULT_GRAPH);
	if (!constantValue.startsWith("<"))
	    constantValue = "<" + constantValue + ">";

	query = QueryConstants.parseQuery(query, "GRAPH", constantValue);

	strBody = httpMan.httpSparqlQuery(query, httpMan.get_OutputFormats()
		.get("xml"));

	// Obtain XML document from results
	Iterator<?> iterator = XmlTraverse.createSparqlXMLIterator(strBody[0]);
	if (iterator != null) {
	    while (iterator.hasNext()) {

		// Obtain the list of 'binding' elements as a sibling node of
		// 'result'
		// For each element 'result' the first binding node is the
		// object identifier
		// the second binding element is the data stream name
		List<?> bindList = ((Element) iterator.next()).elements();
		Element bind = (Element) bindList.get(0);
		Element insideBind = (Element) bind.elements().get(0); // FEDORA
		// ID
		String idData = insideBind.getText();
		bind = (Element) bindList.get(1);
		insideBind = (Element) bind.elements().get(0); // CREATION DATE
		String dateData = insideBind.getText();
		mList.add(idData + ";" + dateData);
	    }
	    return mList;
	} else {
	    log.info("No results from Sparql Query...");
	    return null;
	}
    }

    /**
     * Initialize
     */
    public void initTree() {
	List<String> myList = new ArrayList<String>();

	try {
		myList = this.getRootCollectionsTitle();
	    // Not empty collections
	    if (myList.size() > 0)
		this.callRecursiveCollectionsTreeNoChildren(myList);

	} catch (MulgaraException e) {
	    log.error("Error:", e);
	}
    }

    public void mulgaraFinaliseHttpConnections() {
    	//Commented while using singleton since can't shutdown the connectionManager
    	//this.httpMan.finaliseConnections();
    }
}
